home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_091 / adlcomp / adlmisc.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  13KB  |  555 lines

  1.     /***************************************************************\
  2.     *                                *
  3.     *    adlmisc.c - miscellaneous compiling routines.        *
  4.     *    Copyright 1987 by Ross Cunniff.                *
  5.     *                                *
  6.     \***************************************************************/
  7.  
  8. #include <stdio.h>
  9.  
  10. #include "adltypes.h"
  11. #include "adlprog.h"
  12. #include "adldef.h"
  13. #include "adlcomp.h"
  14.  
  15. static    int16
  16.     NUMADJ = 1,            /* Number of ADJECs found.        */
  17.     num_local;            /* Number of LOCALs found.        */
  18. extern    int16
  19.     numprep;            /* Number of prep synonyms found.    */
  20.  
  21.  
  22.     /***************************************************************\
  23.     *                                *
  24.     *    get_local() - read and process a possible LOCAL        *
  25.     *    declaration.                        *
  26.     *                                *
  27.     \***************************************************************/
  28.  
  29. get_local()
  30. {
  31.     int16
  32.     i;
  33.  
  34.     num_local = 0;
  35.     if( t_type == LOCAL_D ) {
  36.     /* We found the LOCAL token - get a LOCAL list */
  37.     do {
  38.         /* Get the name of a local */
  39.         lexer();
  40.         if( t_type < 256 )
  41.         _ERR_FIX( ILLEGAL_SYMBOL, '(' );
  42.         insert_local( token, LOCAL, num_local );
  43.  
  44.         lexer();
  45.         if( t_type == '[' ) {
  46.         /* The user wants an array.  Get the size. */
  47.         lexer();
  48.         if( t_type != CONST )
  49.             _ERR_FIX( CONST_EXPECTED, ';' );
  50.         if( t_val < 1 )
  51.             _ERR_FIX( BAD_ARRAY, ';' );
  52.  
  53.         /* Create space on the stack for the locals */
  54.         for( i = 0; i < t_val; i++ )
  55.             newcode( PUSH, 0L );
  56.         num_local += t_val;
  57.  
  58.         /* Pick up the closing bracket */
  59.         lexer();
  60.         if( t_type != ']' )
  61.             _ERR_FIX( BRACKET_EXPECTED, ';' );
  62.  
  63.         /* Pick up the next token */
  64.         lexer();
  65.         }
  66.         else {
  67.         newcode( PUSH, 0L );    /* Allocate space for this local */
  68.         num_local += 1;
  69.         }
  70.     } while( t_type == ',' );
  71.  
  72.     /* The list should be terminated by a semicolon */
  73.     if( t_type != ';' )
  74.         _ERR_FIX( SEMI_EXPECTED, '(' );
  75.  
  76.     /* Skip to the beginning of the routine */
  77.     lexer();
  78.     }
  79.     if( num_local > 31 )
  80.     error( "Number of locals must be less than 32.\n" );
  81. }
  82.  
  83.  
  84.     /***************************************************************\
  85.     *                                *
  86.     *    unget_local() - forget all LOCALS declared in this    *
  87.     *    routine.                        *
  88.     *                                *
  89.     \***************************************************************/
  90.  
  91. unget_local()
  92. {
  93.     del_locals();
  94. }
  95.  
  96.  
  97.     /***************************************************************\
  98.     *                                *
  99.     *    getvars() - get a VAR declaration list.            *
  100.     *                                *
  101.     \***************************************************************/
  102. getvars()
  103. {
  104.     do {
  105.     lexer();
  106.     if( t_type != UNDECLARED )
  107.         _ERR_FIX( ILLEGAL_SYMBOL, ';' );
  108.     insert_sys( token, VAR, NUMVAR );
  109.     lexer();
  110.     if( t_type == '[' ) {
  111.         /* The user wants an array.  Pick up the size. */
  112.         lexer();
  113.         if( t_type != CONST )
  114.         _ERR_FIX( CONST_EXPECTED, ';' );
  115.         if( t_val < 1 )
  116.         _ERR_FIX( BAD_ARRAY, ';' );
  117.         NUMVAR += t_val;
  118.  
  119.         /* Pick up the closing bracket */
  120.         lexer();
  121.         if( t_type != ']' )
  122.         _ERR_FIX( BRACKET_EXPECTED, ';' );
  123.  
  124.         /* Pick up the comma */
  125.         lexer();
  126.     }
  127.     else
  128.         NUMVAR += 1;
  129.     } while( t_type == ',' );
  130.     if( t_type != ';' )
  131.     _ERR_FIX( SEMI_EXPECTED, ';' );
  132. }
  133.  
  134.  
  135.     /***************************************************************\
  136.     *                                *
  137.     *    getlist( t ) - Get a declaration list, such as        *
  138.     *        ADJEC red, green, blue;                *
  139.     *    and insert the tokens where they belong.        *
  140.     *                                *
  141.     \***************************************************************/
  142.   
  143. getlist( t )
  144. int16
  145.     t;            /* The type of the declaration */
  146. {
  147.     int16
  148.     *addr;        /* The address of the counter to be incremented */
  149.  
  150.     /* Get the address and the type of the tokens being declared. */
  151.     switch( t ) {
  152.     case VERB_D    : addr = &NUMVERB;    t = VERB;    break;
  153.     case ROUT_D    : addr = &NUMROUT;    t = ROUTINE;    break;
  154.     case ADJEC_D    : addr = &NUMADJ;    t = ADJEC;    break;
  155.     case ART_D    : addr = 0;        t = ARTICLE;    break;
  156.     case PREP_D    : addr = &numprep;    t = PREP;    break;
  157.     }
  158.  
  159.     /* Actually declare the token list */
  160.     do {
  161.     lexer();
  162.     if( t_type != UNDECLARED )
  163.         /* Only tokens not previously declared are allowed */
  164.         _ERR_FIX( ILLEGAL_SYMBOL, ';' );
  165.  
  166.     if( addr ) {
  167.         /* Declare the token and increment the counter */
  168.         if( t == ROUTINE )
  169.         insert_sys( token, t, *addr );
  170.         else
  171.         insertkey( token, t, *addr, 1 );
  172.         (*addr) += 1;
  173.     }
  174.     else {
  175.         /* Articles are just noise, no values are needed. */
  176.         insertkey( token, t, 0, 1 );
  177.     }
  178.     lexer();
  179.     } while( t_type == ',' );
  180.     if( t_type != ';' )
  181.     _ERR_FIX( SEMI_EXPECTED, ';' );
  182. }
  183.  
  184.  
  185.     /***************************************************************\
  186.     *                                *
  187.     *    getassign() - get an assignment statement like        *
  188.     *        toolbox = tool box;                *
  189.     *    or                            *
  190.     *        SEEN = 3;                    *
  191.     *                                *
  192.     \***************************************************************/
  193.  
  194. int16
  195. getassign( do_insert )
  196. int
  197.     do_insert;
  198. {
  199.     char
  200.     s[ 512 ];        /* Save area for the current token string */
  201.     int16
  202.     t_save,            /* Save area for the current token value */
  203.     retval;
  204.  
  205.     if( do_insert ) {
  206.     /* Save the current token (used to print an error message later) */
  207.     retval = 0;
  208.     strcpy( s, token );
  209.     }
  210.  
  211.     /* Read the next token - it should be '=' */
  212.     lexer();
  213.     if( t_type != '=' )
  214.     _ERR_FIX( EQUAL_EXPECTED, ';' );
  215.  
  216.     /* Read the value of the assignment statement */
  217.     lexer();
  218.     if( (t_type == ADJEC) || (t_type == VERB) ) {
  219.     /* We may be reading a noun phrase */
  220.     if( t_type == ADJEC )
  221.         t_save = t_val;
  222.     else
  223.         t_save = -t_val;
  224.     lexer();
  225.     if( t_type == NOUN ) {
  226.         if( (t_save = noun_exists( t_save, t_val )) < 0 )
  227.         _ERR_FIX( "Undeclared object.", ';' );
  228.         if( do_insert )
  229.         insertkey( s, NOUN_SYN, t_save, 1 );
  230.         else
  231.         retval = t_save;
  232.         lexer();
  233.     }
  234.     else if( t_type == ';' ) {
  235.         /* This was just foo = ADJEC or foo = VERB */
  236.         if( do_insert ) {
  237.         if( t_save < 0 )
  238.             insertkey( s, VERB, -t_save, 0 );
  239.         else
  240.             insertkey( s, ADJEC, t_save, 0 );
  241.         }
  242.         else {
  243.         if( t_save < 0 )
  244.             retval = -t_save;
  245.         else
  246.             retval = t_save;
  247.         }
  248.     }
  249.     else
  250.         _ERR_FIX( SEMI_EXPECTED, ';' );
  251.     }
  252.     else if( t_type == NOUN ) {
  253.     /* Unmodified object */
  254.     if( (t_save = noun_exists( 0, t_val )) < 0 )
  255.         _ERR_FIX( ATTEMPT, ';' );
  256.     if( do_insert )
  257.         insertkey( s, NOUN_SYN, t_save, 1 );
  258.     else
  259.         retval = t_save;
  260.     lexer();
  261.     }
  262.     else if( (t_type >= MIN_LEGAL) && (t_type <= MAX_LEGAL) ) {
  263.         /* We're reading a simple synonym */
  264.     if( do_insert ) {
  265.         if( (t_type >= MIN_RT) && (t_type <= MAX_RT) && (t_type != STRING) )
  266.         insertkey( s, t_type, t_val, 0 );
  267.         else
  268.         insert_sys( s, t_type, t_val );
  269.     }
  270.     else
  271.         retval = t_val;
  272.     lexer();
  273.     }
  274.     else if( (t_type == '(') || (t_type == LOCAL_D) ) {
  275.     /* We're creating a routine */
  276.     if( do_insert )
  277.         insert_sys( s, ROUTINE, NUMROUT );
  278.     else
  279.         retval = NUMROUT;
  280.     routspace[ NUMROUT++ ] = currcode();
  281.     get_local();
  282.     getroutine( 1 );
  283.     newcode( RET, 0L );
  284.     unget_local();
  285.     }
  286.     if( t_type != ';' )
  287.     _ERR_FIX( SEMI_EXPECTED, ';' );
  288.     return retval;
  289. }
  290.  
  291.     /***************************************************************\
  292.     *                                *
  293.     *    adlrout( t_read ) - read in an ADL routine and return    *
  294.     *    its starting address.  If t_read is false, the initial    *
  295.     *    '=' [ locals ] '(' sequence is read from the input    *
  296.     *     stream.                        *
  297.     *                                *
  298.     \***************************************************************/
  299.  
  300. address
  301. adlrout( t_read )
  302. int16
  303.     t_read;
  304. {
  305.     address
  306.     t;
  307.  
  308.     if( !t_read ) {
  309.     lexer();
  310.     if( t_type != '=' )
  311.         _ERR_FX0( EQUAL_EXPECTED, ';' );
  312.     lexer();
  313.     if( (t_type != '(') && (t_type != LOCAL_D) )
  314.         _ERR_FX0( LEFT_EXPECTED, ';' );
  315.     }
  316.     t = currcode();
  317.     get_local();
  318.     getroutine( 1 );
  319.     newcode( RET, 0L );
  320.     unget_local();
  321.     if( t_type != ';' )
  322.     _ERR_FX0( SEMI_EXPECTED, ';' );
  323.     return t;
  324. }
  325.  
  326.  
  327.     /***************************************************************\
  328.     *                                *
  329.     *    getverb() - handle things like                *
  330.     *        north(PREACT) = ($setg GOVERB TRUE);        *
  331.     *    or                            *
  332.     *        north ball(WEIGH) = 300;            *
  333.     *                                *
  334.     \***************************************************************/
  335.  
  336. getverb()
  337. {
  338.     int16
  339.      verb,        /* The verb which is under consideration */
  340.      val,        /* The property which is being assigned */
  341.      rval;        /* The 16-bit value of the RHS of the expression */
  342.  
  343.     verb = t_val;
  344.     lexer();
  345.     if( t_type == NOUN ) {
  346.     /* This is actually a noun assignment */
  347.     nounassign( 2, -verb );
  348.     return;
  349.     }
  350.     else if( t_type == PREP ) {
  351.     /* This is actually a VERB PREP = VERB statement */
  352.     getverbsyn( verb );
  353.     return;
  354.     }
  355.  
  356.     /* This is a verb assignment.  Get the property number. */
  357.     if( t_type != '(' )
  358.     _ERR_FIX( LEFT_EXPECTED, ';' );
  359.     lexer();
  360.     if( t_type != CONST )
  361.     _ERR_FIX( CONST_EXPECTED, ';' );
  362.     if( (t_val != _PREACT) && (t_val != _ACT) )
  363.     _ERR_FIX( "PREACT or ACTION expected.\n", ';' );
  364.     val = t_val;
  365.     lexer();
  366.     if( t_type != ')' )
  367.     _ERR_FIX( RIGHT_EXPECTED, ';' );
  368.  
  369.     /* Get the RHS of the expression - it must be a routine ID or a routine */
  370.     lexer();
  371.     if( t_type != '=' )
  372.     _ERR_FIX( EQUAL_EXPECTED, ';' );
  373.     lexer();
  374.     if( t_type == ROUTINE ) {
  375.     rval = t_val;
  376.     lexer();
  377.     if( t_type != ';' )
  378.         _ERR_FIX( SEMI_EXPECTED, ';' );
  379.     }
  380.     else if( (t_type == '(') || (t_type == LOCAL_D) ) {
  381.     rval = NUMROUT;
  382.     routspace[ NUMROUT++ ] = adlrout( 1 );
  383.     }
  384.     else
  385.     _ERR_FIX( "Routine expected", ';' );
  386.  
  387.     /* Put the RHS into the proper property. */
  388.     switch( val ) {
  389.     case _PREACT :
  390.         if( verbspace[ verb ].preact )
  391.         warning( "verb( PREACT ) already assigned.\n" );
  392.         verbspace[ verb ].preact = rval;
  393.         break;
  394.     case _ACT :
  395.         if( verbspace[ verb ].postact )
  396.         warning( "verb( ACTION ) already assigned.\n" );
  397.         verbspace[ verb ].postact = rval;
  398.         break;
  399.     }
  400. }
  401.  
  402.  
  403.     /***************************************************************\
  404.     *                                *
  405.     *    globassign() - Read and process a statement such as    *
  406.     *        (MaxScore) = 400;                *
  407.     *                                *
  408.     \***************************************************************/
  409.  
  410. globassign()
  411. {
  412.     int16
  413.     v;    /* The actual variable id */
  414.  
  415.     /* Read the variable */
  416.     lexer();
  417.     if( t_type != VAR )
  418.     _ERR_FIX( VAR_EXPECTED, ';' );
  419.     v = t_val;
  420.  
  421.     lexer();
  422.     if( t_type == '+' ) {
  423.     /* The user wants to assign into an array.  Get the offset. */
  424.     lexer();
  425.     if( t_type != CONST )
  426.         _ERR_FIX( CONST_EXPECTED, ';' );
  427.     v += t_val;
  428.  
  429.     /* Pick up the closing parenthesis */
  430.     lexer();
  431.     }
  432.  
  433.     if( t_type != ')' )
  434.     _ERR_FIX( RIGHT_EXPECTED, ')' );
  435.  
  436.     if( varspace[ v ] )
  437.     warning( "Re-assignment of VAR value.\n" );
  438.  
  439.     /* Get the RHS and stuff it into the correct place. */
  440.     varspace[ v ] = getassign( 0 );
  441. }
  442.  
  443.  
  444.     /***************************************************************\
  445.     *                                *
  446.     *    routassign() - handle the assignment of an actual    *
  447.     *    routine to a previously declared routine ID.        *
  448.     *                                *
  449.     \***************************************************************/
  450.  
  451. routassign()
  452. {
  453.     int16
  454.     v;    /* The routine ID */
  455.  
  456.     v = t_val;
  457.     if( routspace[ v ] )
  458.     warning( "Re-assignment of ROUTINE value.\n" );
  459.     routspace[ v ] = adlrout( 0 );
  460. }
  461.  
  462.  
  463.     /***************************************************************\
  464.     *                                *
  465.     *    prepassign() - handle constructs like            *
  466.     *        in front of = before;                *
  467.     *                                *
  468.     \***************************************************************/
  469.  
  470. prepassign()
  471. {
  472.     int16
  473.     adj;
  474.  
  475.     /* Save the value of the first preposition */
  476.     prepspace[ NUMPP ].first = t_val;
  477.  
  478.     /* Get the middle part of the phrase */
  479.     lexer();
  480.     if( t_type == NOUN_SYN ) {
  481.     prepspace[ NUMPP ].obj = t_val;
  482.     lexer();
  483.     }
  484.     else if( t_type != PREP ) {
  485.     if( t_type == VERB ) {
  486.         adj = -t_val;
  487.         lexer();
  488.     }
  489.     else if( t_type == ADJEC ) {
  490.         adj = t_val;
  491.         lexer();
  492.     }
  493.     else
  494.         adj = 0;
  495.     if( t_type != NOUN )
  496.         _ERR_FIX( NOUN_WANTED, ';' );
  497.     if( (prepspace[ NUMPP ].obj = noun_exists( adj, t_val )) < 0 )
  498.         _ERR_FIX( "Illegal object.\n", ';' );
  499.     lexer();
  500.     }
  501.  
  502.     /* Get the second preposition and save it */
  503.     if( t_type != PREP )
  504.     _ERR_FIX( PREP_EXPECTED, ';' );
  505.     prepspace[ NUMPP ].last = t_val;
  506.  
  507.     /* Get the '=' PREP ';' */
  508.     lexer();
  509.     if( t_type != '=' )
  510.     _ERR_FIX( EQUAL_EXPECTED, '=' );
  511.     lexer();
  512.     if( t_type != PREP )
  513.     _ERR_FIX( PREP_EXPECTED, ';' );
  514.     prepspace[ NUMPP ].val = t_val;
  515.     lexer();
  516.     if( t_type != ';' )
  517.     _ERR_FIX( SEMI_EXPECTED, ';' );
  518.     NUMPP++;
  519. }
  520.  
  521.  
  522.     /***************************************************************\
  523.     *                                *
  524.     *    getverbsyn( verb ) - get a statement like        *
  525.     *        put on = wear;                    *
  526.     *                                *
  527.     \***************************************************************/
  528.  
  529. getverbsyn( verb )
  530. int16
  531.     verb;
  532. {
  533.     /* At this point, we have VERB PREP */
  534.     verbsyn[ NUMVS ].vrb = verb;
  535.     verbsyn[ NUMVS ].prp = t_val;
  536.  
  537.     /* Get the equals sign */
  538.     lexer();
  539.     if( t_type != '=' )
  540.     _ERR_FIX( EQUAL_EXPECTED, ';' );
  541.  
  542.     /* Get the following verb */
  543.     lexer();
  544.     if( t_type != VERB )
  545.     _ERR_FIX( "VERB expected.\n", ';' );
  546.     verbsyn[ NUMVS++ ].val = t_val;
  547.  
  548.     /* Get the closing semicolon */
  549.     lexer();
  550.     if( t_type != ';' )
  551.     _ERR_FIX( SEMI_EXPECTED, ';' );
  552. }
  553.  
  554. /*** EOF adlmisc.c ***/
  555.